from flask import (_request_ctx_stack, abort, current_app, flash, redirect,
                   request, session)
from flask_login import LoginManager as OriLoginManager
from itsdangerous import TimestampSigner
from app.logging_service import logger_web


class LoginManager(OriLoginManager):
    def get_unionid(self):
        """
        check if the user is logged in
        :return:
        """
        from flask import session
        from itsdangerous import TimestampSigner, SignatureExpired, BadTimeSignature
        from acm_utils import acm_config
        if 'access_token' not in session:
            return None
        s = TimestampSigner(str(acm_config["SECRET_KEY"]))
        try:
            return s.unsign(str((session["access_token"])), max_age=14 * 60 * 60 * 24).decode(encoding='UTF-8')
        except SignatureExpired as e:
            if 'access_token' in session:
                del session["access_token"]
            logger_web.info('session expired: %s' % str(e))
            return None
        except Exception as e:
            if 'access_token' in session:
                del session["access_token"]
            logger_web.error('!!!login error: %s' % str(e))
            return None

    # def reload_user(self, user=None):
    #     ctx = _request_ctx_stack.top
    #
    #     if user is None:
    #         user_id = self.get_unionid()
    #         if user_id is None:
    #             ctx.user = self.anonymous_user()
    #         else:
    #             if self.user_callback is None:
    #                 raise Exception(
    #                     "No user_loader has been installed for this "
    #                     "LoginManager. Refer to"
    #                     "https://flask-login.readthedocs.io/"
    #                     "en/latest/#how-it-works for more info.")
    #             user = self.user_callback(user_id)
    #             if user is None:
    #                 ctx.user = self.anonymous_user()
    #             else:
    #                 ctx.user = user
    #     else:
    #         ctx.user = user


def login_user(user, remember=False, duration=None, force=False, fresh=True):
    from app import app
    if not force and not user.is_active:
        return False
    s = TimestampSigner(app.config['SECRET_KEY'])
    session.permanent = True
    session["access_token"] = s.sign(user.unionid).decode(encoding="UTF-8")
    session['_fresh'] = fresh
    if remember:
        session['remember'] = 'set'
        if duration is not None:
            try:
                session['remember_seconds'] = duration.total_seconds()
            except AttributeError:
                raise Exception('duration must be a datetime.timedelta, '
                                'instead got: {0}'.format(duration))
    session.accessed = False
    return True
